package com.hhf.springboot.controller;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hhf.springboot.annotation.AuthCheck;
import com.hhf.springboot.common.*;
import com.hhf.springboot.constant.ProjectStatusConstant;
import com.hhf.springboot.constant.UserConstant;
import com.hhf.springboot.exception.BusinessException;
import com.hhf.springboot.exception.ThrowUtils;
import com.hhf.springboot.manager.FileManager;
import com.hhf.springboot.model.dto.bisheProject.*;
import com.hhf.springboot.model.entity.BisheProject;
import com.hhf.springboot.model.entity.User;
import com.hhf.springboot.model.vo.BisheProjectVO;
import com.hhf.springboot.model.vo.WordCloud;
import com.hhf.springboot.service.BisheProjectService;
import com.hhf.springboot.service.UserService;
import com.hhf.springboot.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * 毕设项目接口
 *
 * @author hhf
 * @from <a href="https://gitee.com/hanhuaifei/projects">我的gitee</a>
 * @Date 2024/9/26
 */
@RestController
@RequestMapping("/bisheProject")
@Slf4j
public class BisheProjectController {

    @Resource
    private BisheProjectService bisheProjectService;

    @Resource
    private UserService userService;

    @Resource
    private FileManager fileManager;


    /**
     * 获取 bisheProject 统计数据
     *
     * @return
     */
    @GetMapping("/statistics")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<BisheProjectStatisticsDTO> getBisheStatistics() {
        BisheProjectStatisticsDTO bisheStatistics = bisheProjectService.getBisheStatistics();
        return Result.success(bisheStatistics);
    }


    /**
     * 获取 bisheProject 标签词云统计数据
     * @return
     */
    @GetMapping("/wordCloud/tag")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<List<WordCloud>> getBisheProjectTagWordCloud() {
        return Result.success(bisheProjectService.getBisheProjectTagWordCloud());
    }


    /**
     * 获取 bisheProject 的点击量(clickNum)总数量
     *
     * @return
     */
    @GetMapping("/count/clickNum")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Long> getClickNumTotalCount() {
        return Result.success(bisheProjectService.getClickNumTotalCount());
    }


    /**
     * 获取 bisheProject 的总的数量
     *
     * @return
     */
    @GetMapping("/count")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Long> getTotalCount() {
        return Result.success(bisheProjectService.count());
    }


    /**
     * 浏览
     *
     * @param bisheProjectId
     * @return resultNum 本次点赞变化数
     */
    @GetMapping("/click")
    public BaseResponse<Long> doBisheProjectClick(Long bisheProjectId) {
        if (bisheProjectId == null || bisheProjectId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        return Result.success(bisheProjectService.doClick(bisheProjectId));
    }


    /**
     * 根据 id 下载毕设项目的文件
     *
     * @param id
     * @return
     */
    @GetMapping("/download")
    public void downloadBisheProjectById(long id, HttpServletRequest request, HttpServletResponse response) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        // 查询数据库
        BisheProject bisheProject = bisheProjectService.getById(id);
        ThrowUtils.throwIf(bisheProject == null, ErrorCode.NOT_FOUND_ERROR);
        String codeDataUrl = bisheProject.getCodeDataUrl();


        //查询订单查看是否有下载权限


        //获取下载的文件路径
        String filepath = codeDataUrl;


        //文件下载
        try {
            fileManager.downloadFile(filepath, response);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    // region 增删改查

    /**
     * 创建毕设项目
     *
     * @param bisheProjectAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Long> addBisheProject(@RequestBody BisheProjectAddRequest bisheProjectAddRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(bisheProjectAddRequest == null, ErrorCode.PARAMS_ERROR);
        // 在此处将实体类和 DTO 进行转换
        BisheProject bisheProject = new BisheProject();
        BeanUtils.copyProperties(bisheProjectAddRequest, bisheProject);
        List<String> tags = bisheProjectAddRequest.getTagList();
        if (tags != null) {
            bisheProject.setTags(JSONUtil.toJsonStr(tags));
        }
        // 数据校验
        bisheProjectService.validBisheProject(bisheProject, true);
        // 填充默认值
        User loginUser = userService.getLoginUser(request);
        bisheProject.setUserId(loginUser.getId());
        bisheProject.setStatus(ProjectStatusConstant.OPEN);
        bisheProject.setClickNum(0L);
        // 写入数据库
        boolean result = bisheProjectService.save(bisheProject);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        // 返回新写入的数据 id
        long newBisheProjectId = bisheProject.getId();
        return Result.success(newBisheProjectId);
    }

    /**
     * 删除毕设项目
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteBisheProject(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = userService.getLoginUser(request);
        long id = deleteRequest.getId();
        // 判断是否存在
        BisheProject oldBisheProject = bisheProjectService.getById(id);
        ThrowUtils.throwIf(oldBisheProject == null, ErrorCode.NOT_FOUND_ERROR);
        // 仅本人或管理员可删除
        if (!oldBisheProject.getUserId().equals(user.getId()) && !userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 操作数据库
        boolean result = bisheProjectService.removeById(id);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return Result.success(true);
    }

    /**
     * 更新毕设项目（仅管理员可用）
     *
     * @param bisheProjectUpdateRequest
     * @return
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateBisheProject(@RequestBody BisheProjectUpdateRequest bisheProjectUpdateRequest) {
        if (bisheProjectUpdateRequest == null || bisheProjectUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 在此处将实体类和 DTO 进行转换
        BisheProject bisheProject = new BisheProject();
        BeanUtils.copyProperties(bisheProjectUpdateRequest, bisheProject);
        List<String> tags = bisheProjectUpdateRequest.getTagList();
        if (tags != null) {
            bisheProject.setTags(JSONUtil.toJsonStr(tags));
        }

        // 数据校验
        bisheProjectService.validBisheProject(bisheProject, false);
        // 判断是否存在
        long id = bisheProjectUpdateRequest.getId();
        BisheProject oldBisheProject = bisheProjectService.getById(id);
        ThrowUtils.throwIf(oldBisheProject == null, ErrorCode.NOT_FOUND_ERROR);
        // 操作数据库
        boolean result = bisheProjectService.updateById(bisheProject);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return Result.success(true);
    }

    /**
     * 根据 id 获取毕设项目（封装类）
     *
     * @param id
     * @return
     */
    @GetMapping("/get/vo")
    public BaseResponse<BisheProjectVO> getBisheProjectVOById(long id, HttpServletRequest request) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        // 查询数据库
        BisheProject bisheProject = bisheProjectService.getById(id);
        ThrowUtils.throwIf(bisheProject == null, ErrorCode.NOT_FOUND_ERROR);
        // 获取封装类
        return Result.success(bisheProjectService.getBisheProjectVO(bisheProject, request));
    }

    /**
     * 分页获取毕设项目列表（仅管理员可用）
     *
     * @param bisheProjectQueryRequest
     * @return
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<BisheProject>> listBisheProjectByPage(@RequestBody BisheProjectQueryRequest bisheProjectQueryRequest) {
        long current = bisheProjectQueryRequest.getCurrent();
        long size = bisheProjectQueryRequest.getPageSize();
        // 查询数据库
        Page<BisheProject> bisheProjectPage = bisheProjectService.page(new Page<>(current, size),
                bisheProjectService.getQueryWrapper(bisheProjectQueryRequest));

        return Result.success(bisheProjectService.getBisheProjectPage(bisheProjectPage));
    }

    /**
     * 分页获取毕设项目列表（封装类）
     *
     * @param bisheProjectQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<BisheProjectVO>> listBisheProjectVOByPage(@RequestBody BisheProjectQueryRequest bisheProjectQueryRequest,
                                                                       HttpServletRequest request) {
        long current = bisheProjectQueryRequest.getCurrent();
        long size = bisheProjectQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        // 查询数据库
        Page<BisheProject> bisheProjectPage = bisheProjectService.page(new Page<>(current, size),
                bisheProjectService.getQueryWrapper(bisheProjectQueryRequest));
        // 获取封装类
        return Result.success(bisheProjectService.getBisheProjectVOPage(bisheProjectPage, request));
    }

    /**
     * 分页获取当前登录用户创建的毕设项目列表
     *
     * @param bisheProjectQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/my/list/page/vo")
    public BaseResponse<Page<BisheProjectVO>> listMyBisheProjectVOByPage(@RequestBody BisheProjectQueryRequest bisheProjectQueryRequest,
                                                                         HttpServletRequest request) {
        ThrowUtils.throwIf(bisheProjectQueryRequest == null, ErrorCode.PARAMS_ERROR);
        // 补充查询条件，只查询当前登录用户的数据
        User loginUser = userService.getLoginUser(request);
        bisheProjectQueryRequest.setUserId(loginUser.getId());
        long current = bisheProjectQueryRequest.getCurrent();
        long size = bisheProjectQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        // 查询数据库
        Page<BisheProject> bisheProjectPage = bisheProjectService.page(new Page<>(current, size),
                bisheProjectService.getQueryWrapper(bisheProjectQueryRequest));
        // 获取封装类
        return Result.success(bisheProjectService.getBisheProjectVOPage(bisheProjectPage, request));
    }

    /**
     * 编辑毕设项目（给用户使用）
     *
     * @param bisheProjectEditRequest
     * @param request
     * @return
     */
    @PostMapping("/edit")
    public BaseResponse<Boolean> editBisheProject(@RequestBody BisheProjectEditRequest bisheProjectEditRequest, HttpServletRequest request) {
        if (bisheProjectEditRequest == null || bisheProjectEditRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 在此处将实体类和 DTO 进行转换
        BisheProject bisheProject = new BisheProject();
        BeanUtils.copyProperties(bisheProjectEditRequest, bisheProject);
        List<String> tags = bisheProjectEditRequest.getTagList();
        if (tags != null) {
            bisheProject.setTags(JSONUtil.toJsonStr(tags));
        }
        // 数据校验
        bisheProjectService.validBisheProject(bisheProject, false);
        User loginUser = userService.getLoginUser(request);
        // 判断是否存在
        long id = bisheProjectEditRequest.getId();
        BisheProject oldBisheProject = bisheProjectService.getById(id);
        ThrowUtils.throwIf(oldBisheProject == null, ErrorCode.NOT_FOUND_ERROR);
        // 仅本人或管理员可编辑
        if (!oldBisheProject.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 操作数据库
        boolean result = bisheProjectService.updateById(bisheProject);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return Result.success(true);
    }

    /**
     * 日新增统计毕设项目
     *
     * @return
     */
    @PostMapping("/day/newly/added")
    public BaseResponse<List<DataGroupByDateDTO>> dayNewlyAddedBisheProject() {
        // 今天
        Date endDate = DateUtils.getNow();
        // 30天以前
        Date beginDate = DateUtils.dayAfter(endDate, -30);
        // 查询
        List<DataGroupByDateDTO> bisheProjectDataList = bisheProjectService.countByDay(beginDate, endDate);
        //返回结果
        return Result.success(bisheProjectDataList);

    }

    // endregion
}
